/* 
 * Enterprise Library Extensions - DI + ORM.
 * Copyright (C) 2006
 *
 * GNU General Public License
 *
 * This program is free software; you can redistribute 
 * it and/or modify it under the terms of the GNU General Public License 
 * as published by the Free Software Foundation; either version 2 of the 
 * License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful, but 
 * WITHOUT ANY WARRANTY; without even the implied warranty of 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
 * See the GNU General Public License for more details.
 */
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing.Design;
using Microsoft.Practices.EnterpriseLibrary.Configuration.Design;
using Microsoft.Practices.EnterpriseLibrary.Configuration.Design.Validation;
using ELE.EnterpriseLibrary.Data.Configuration.Design.Properties;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
using System.Configuration;
using System.Reflection;
using ELE.EnterpriseLibrary.Common.Configuration.Design;

namespace ELE.EnterpriseLibrary.Data.Configuration.Design
{

  [Image(typeof(ObjectBindingNode))]
  [SelectedImage(typeof(ObjectBindingNode))]
  public class ObjectBindingNode : ConfigurationNode, IObjectTypeReferencingObject
  {
    private string columnName;
    private bool isIgnore;
    private string inName;
    private bool isCollection;
    private string jointBinding;
    private string jointColumn;
    private string jointTable;
    private string nullableValue;
    private string outName;
    private bool isPrimaryKey;
    private string property;
    private string refType;
    private string sqlType;

    public ObjectBindingNode()
      : this(new PropertyBindingData(Resource.DefaultObjectBindingName))
    {
        
    }

    public ObjectBindingNode(PropertyBindingData data)
      : base((data == null) ? Resource.DefaultObjectBindingName : data.Name)
    {
      if (data == null) { throw new ArgumentNullException("PropertyBindingData"); }
      columnName = data.ColumnName;
      isIgnore = data.Ignore;
      inName = data.InName;
      isCollection = data.IsCollection;
      jointBinding = data.JointBinding;
      jointColumn = data.JointColumn;
      jointTable = data.JointTable;
      nullableValue = data.NullableValue;
      outName = data.OutName;
      isPrimaryKey = data.PrimaryKey;
      property = data.Property;
      refType = data.RefType;
      sqlType = data.SqlType;
    }
    private string NonEmptyString(string val)
    {
      if (string.IsNullOrEmpty(val)) return null;
      return val;
    }
    [Browsable(false)]
    public PropertyBindingData BindingData
    {
      get
      {
        PropertyBindingData data = new PropertyBindingData(Name);
        data.InName = this.NonEmptyString(this.InName);
        data.JointBinding = this.NonEmptyString(this.JointBinding);
        data.JointColumn = this.NonEmptyString(this.JointColumn);
        data.JointTable = this.NonEmptyString(this.JointTable);
        data.NullableValue = this.NonEmptyString(this.NullableValue);
        data.OutName = this.NonEmptyString(this.OutName);
        data.Property = this.NonEmptyString(this.BoundProperty);
        data.RefType = this.NonEmptyString(this.ReferencedType);
        data.SqlType = this.NonEmptyString(this.SqlType);
        data.Ignore = this.Ignore;
        data.IsCollection = this.IsCollection;
        data.PrimaryKey = this.IsPrimaryKey;

	      return data;
      }
    }

    public string ColumnName
    {
      get { return columnName; }
      set { columnName = value; }
    }

    public bool Ignore
    {
      get { return isIgnore; }
      set { isIgnore = value; }
    }

    public string InName
    {
      get { return inName; }
      set { inName = value; }
    }

    public bool IsCollection
    {
      get { return isCollection; }
      set { isCollection = value; }
    }

    public string JointBinding
    {
      get { return jointBinding; }
      set { jointBinding = value; }
    }

    public string JointColumn
    {
      get { return jointColumn; }
      set { jointColumn = value; }
    }

    public string JointTable
    {
      get { return jointTable; }
      set { jointTable = value; }
    }

    public string NullableValue
    {
      get { return nullableValue; }
      set { nullableValue = value; }
    }

    public string OutName
    {
      get { return outName; }
      set { outName = value; }
    }

    public bool IsPrimaryKey
    {
      get { return isPrimaryKey; }
      set { isPrimaryKey = value; }
    }

    [Required]
    [SRDescription("ObjectPropertyBoundDescription", typeof(Resource))]
    [Editor(typeof(ObjectPropertySelectorEditor), typeof(UITypeEditor))]
    [SRCategory("CategoryGeneral", typeof(Resource))]
    public string BoundProperty
    {
      get { return property; }
      set { property = value; }
    }

    public string ReferencedType
    {
      get { return refType; }
      set { refType = value; }
    }

    public string SqlType
    {
      get { return sqlType; }
      set { sqlType = value; }
    }


    #region IObjectTypeReferencingObject Members

    public Type GetReferencedType()
    {
      if(this.Parent.Parent != null)
      {
        ObjectMappingNode mapNode = (ObjectMappingNode)this.Parent.Parent;
        if (mapNode.Type != null)
        {
          return mapNode.Type.Type;
        }
      }
      return null;
    }

    public string GetReferencedTypeName()
    {
      return GetReferencedType().FullName;
    }

    #endregion
  }
}